package com.wonders.demo.module.controller;

import com.wonders.demo.module.po.UserPo;
import com.wonders.demo.module.service.UserService;
import com.wonders.demo.utils.VerifyCode;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;

/**
 * @author wonders
 */
@Controller
@RequestMapping("/sys/user")
public class LoginController {

    @Resource
    private UserService userService;

    @PostMapping("/login")
    public String login(String username, String password, String code, HttpServletRequest request) {
        String verifyCode = (String) request.getSession().getAttribute("verifyCode");
        try {
            if (code.equalsIgnoreCase(verifyCode)) {
                Subject subject = SecurityUtils.getSubject();
                UsernamePasswordToken token = new UsernamePasswordToken(username, password);
                subject.login(token);
                return "redirect:/index.jsp";
            }
            throw new RuntimeException("验证码错误！");
        } catch (UnknownAccountException e) {
            System.out.println("用户名错误");
        } catch (IncorrectCredentialsException e) {
            System.out.println("密码错误");
        } catch (Exception e) {
            System.out.println("系统内部错误");
        }
        return "redirect:/login.jsp";
    }

    @GetMapping("/logout")
    public String logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return "redirect:/login.jsp";
    }


    @PostMapping("/register")
    public String register(UserPo user) {
        String salt = new SecureRandomNumberGenerator().nextBytes().toString();
        user.setSalt(salt);
        String password = new SimpleHash("md5", user.getPassword(), salt, 1024).toString();
        user.setPassword(password);
        userService.save(user);
        return "redirect:/login.jsp";
    }


    @GetMapping("/code")
    public void getVerificationCode(HttpServletResponse response, HttpServletRequest request) {
        try {
            int width = 200;
            int height = 69;
            BufferedImage verifyImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            //生成对应宽高的初始图片
            String randomText = VerifyCode.drawRandomText(width, height, verifyImg);
            //单独的一个类方法，出于代码复用考虑，进行了封装。
            //功能是生成验证码字符并加上噪点，干扰线，返回值为验证码字符
            request.getSession().setAttribute("verifyCode", randomText);
            response.setContentType("image/png");//必须设置响应内容类型为图片，否则前台不识别
            OutputStream os = response.getOutputStream(); //获取文件输出流
            ImageIO.write(verifyImg, "png", os);//输出图片流
            os.flush();
            os.close();//关闭流
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
